using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;

namespace ClientTools.Client.Controls.Media
{
    public partial class ucMedia : BaseUserControl, IUserControl
    {

        private Library.Interfaces.IMedia _actMedia;

        public ucMedia()
        {
            InitializeComponent();
        }

        #region I_UserControl Member

        public void SetData(ClientTools.Client.Library.Settings.Profile profile)
        {
            this.ActProfile = profile;
            this.ActProfile.InitProvider();
            this.ActProvider = this.ActProfile.ProviderObject;

            if (!this.ImplementsMedia())
            {
                this.Enabled = false;
                return;
            }

            this._actMedia = (Library.Interfaces.IMedia)this.ActProvider;
            this.ClearData();
            this.Enabled = true;
        }

        public string Header
        {
            get { return "Media Upload"; }
        }

        public Image ButtonImage
        {
            get { return this.tsbAddImage.Image; }
        }

        public int Sort
        {
            get { return 3; }
        }

        public bool ShowDelimiter
        {
            get { return true; }
        }

        public string ButtonText
        {
            get { return "Media Upload"; }
        }

        #endregion

        private void ClearData()
        { 
            this.tvMedias.Nodes.Clear();
            this.SplitContainer1.Enabled = false;
        }

        private void tsbMedias_Click(object sender, EventArgs e)
        {
            this.Cursor = Cursors.WaitCursor;

            this.tvMedias_NodeMouseClick(null, null);

            this.tvMedias.SuspendLayout();
            this.tvMedias.Nodes.Clear();

            try 
	        {
                ClientTools.Library.Media.MediaCollection medias = this._actMedia.GetRootMedias(true);
                this.AddChildNodes(medias, this.tvMedias.Nodes);
	        }
	        catch (Exception)
	        {
                //RaiseEvent ShowNotImplemented();
		        throw;
	        }

            this.tvMedias.ExpandAll();
            this.tvMedias.ResumeLayout();

            this.SplitContainer1.Enabled = true;

            this.Cursor = Cursors.Default;
        }

        private void tvMedias_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            this.tsbAddFile.Enabled = false;
            this.tsbAddFolder.Enabled = false;
            this.tsbAddImage.Enabled = false;
            this.tsbAddStructure.Enabled = false;
            this.tsbDeleteMedia.Enabled = false;
            if (e != null && e.Node != null)
            {
                this.tsbDeleteMedia.Enabled = true;
                switch (((ClientTools.Library.Media.Media)e.Node.Tag).NodeTypeAlias)
                {
                    case "Folder":
                        this.tsbAddFile.Enabled = true;
                        this.tsbAddFolder.Enabled = true;
                        this.tsbAddImage.Enabled = true;
                        this.tsbAddStructure.Enabled = true;
                        break;
                    default:
                        break;
                }
            }
        }

        private void AddChildNodes(ClientTools.Library.Media.MediaCollection umbracoMedias, TreeNodeCollection treeNodes)
        {
            foreach (ClientTools.Library.Media.Media umbracoMedia in umbracoMedias)
            {
                TreeNode treeNode = treeNodes.Add(umbracoMedia.Name);
                treeNode.Tag = umbracoMedia;
                this.SetImageIndex(treeNode, umbracoMedia.NodeTypeAlias);
                this.AddChildNodes(umbracoMedia.Children, treeNode.Nodes);
            }
        }

        private void SetImageIndex(TreeNode node, String nodeType)
        {
            switch (nodeType)
            {
                case "Folder":
                    node.ImageIndex = 0;
                    node.SelectedImageIndex = 1;
                    break;
                case "Image":
                    node.ImageIndex = 2;
                    node.SelectedImageIndex = 2;
                    break;
                case "File":
                    node.ImageIndex = 4;
                    node.SelectedImageIndex = 4;
                    break;
                default:
                    break;
            }
        }

        private void tsbDeleteMedia_Click(object sender, EventArgs e)
        {
            if (this.tvMedias.SelectedNode == null)
	        {
		        MessageBox.Show("No node selected!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
	        }
            string msg;
            switch (((ClientTools.Library.Media.Media)this.tvMedias.SelectedNode.Tag).NodeTypeAlias)
	        {
                case "Folder":
                    msg = "Are you sure that you want to delete the folder '" + this.tvMedias.SelectedNode.Text + "' with all his childs?";
                    break;
                case "Image":
                    msg = "Are you sure that you want to delete the image '" + this.tvMedias.SelectedNode.Text + "'?";
                    break;
                case "File":
                    msg = "Are you sure that you want to delete the file '" + this.tvMedias.SelectedNode.Text + "'?";
                    break;
		        default:
                    msg = "Are you sure that you want to delete the media '" + this.tvMedias.SelectedNode.Text + "'?";
                    break;
	        }
            if (MessageBox.Show(msg, "Question", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
            {
                this.Cursor = Cursors.WaitCursor;
                this.DeleteMediaNode(this.tvMedias.SelectedNode);
                this.tvMedias.SelectedNode.Parent.Nodes.Remove(this.tvMedias.SelectedNode);
                this.Cursor = Cursors.Default;
            }
        }

        private void DeleteMediaNode(TreeNode treeNode)
        {
            foreach (TreeNode childNode in treeNode.Nodes)
            {
                this.DeleteMediaNode(childNode);
            }
            this._actMedia.DeleteMedia(((ClientTools.Library.Media.Media)treeNode.Tag).Id);
        }

        private void tsbAddFolder_Click(object sender, EventArgs e)
        {
            if (this.tvMedias.SelectedNode == null)
            {
                MessageBox.Show("There is no node selected!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            ClientTools.Library.Media.Media folder = (ClientTools.Library.Media.Media)this.tvMedias.SelectedNode.Tag;

            using (Dialogs.AddFolderDialog dlg = new ClientTools.Client.Controls.Media.Dialogs.AddFolderDialog())
            {
                if (dlg.ShowDialog(this) == DialogResult.OK)
                {
                    this.Cursor = Cursors.WaitCursor;
                    string s = dlg.txtFoldername.Text;
                    TreeNode treeNode = new TreeNode(s);
                    treeNode.Tag = this._actMedia.CreateFolder(folder.Id, s);
                    this.SetImageIndex(treeNode, "Folder");
                    this.tvMedias.SelectedNode.Nodes.Add(treeNode);
                    this.Cursor = Cursors.Default;
                }
            }
        }

        private void tsbAddImage_Click(object sender, EventArgs e)
        {
            if (this.tvMedias.SelectedNode == null)
            {
                MessageBox.Show("There is no node selected!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            ClientTools.Library.Media.Media folderMedia = (ClientTools.Library.Media.Media)this.tvMedias.SelectedNode.Tag;

            using (Dialogs.AddImageDialog dlg = new ClientTools.Client.Controls.Media.Dialogs.AddImageDialog())
            {
                if (dlg.ShowDialog(this) == DialogResult.OK )
                {
                    this.Cursor = Cursors.WaitCursor;
                    foreach (string s in dlg.lbxImages.Items)
                    {
                        TreeNode treeNode = new TreeNode(System.IO.Path.GetFileName(s));
                        treeNode.Tag = this._actMedia.CreateImage(folderMedia.Id, System.IO.Path.GetFileName(s), this.GetImage(s, dlg.MaxImageSize));
                        this.SetImageIndex(treeNode, "Image");
                        this.tvMedias.SelectedNode.Nodes.Add(treeNode);
                    }
                    this.Cursor = Cursors.Default;
                }
            }
        }

        private void tsbAddFile_Click(object sender, EventArgs e)
        {
            if (this.tvMedias.SelectedNode == null)
            {
                MessageBox.Show("There is no node selected!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            ClientTools.Library.Media.Media folder = (ClientTools.Library.Media.Media)this.tvMedias.SelectedNode.Tag;

            using (Dialogs.AddFileDialog dlg = new ClientTools.Client.Controls.Media.Dialogs.AddFileDialog())
            {
                if (dlg.ShowDialog(this) == DialogResult.OK)
                {
                    this.Cursor = Cursors.WaitCursor;
                    foreach (string s in dlg.lbxImages.Items)
                    {
                        TreeNode treeNode = new TreeNode(System.IO.Path.GetFileName(s));
                        treeNode.Tag = this._actMedia.CreateFile(folder.Id, System.IO.Path.GetFileName(s), this.GetFile(s));
                        this.SetImageIndex(treeNode, "File");
                        this.tvMedias.SelectedNode.Nodes.Add(treeNode);
                    }
                    this.Cursor = Cursors.Default;
                }
            }
        }

        private void tsbAddStructure_Click(object sender, EventArgs e)
        {
            if (this.tvMedias.SelectedNode == null)
            {
                MessageBox.Show("There is no node selected!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            ClientTools.Library.Media.Media folder = (ClientTools.Library.Media.Media)this.tvMedias.SelectedNode.Tag;

            this.tvMedias.SuspendLayout();
            if (this.FolderBrowserDialog1.ShowDialog(this) == DialogResult.OK)
            {
                string selFolder = this.FolderBrowserDialog1.SelectedPath;
                foreach (string folderToAdd in System.IO.Directory.GetDirectories(selFolder))
                {
                    this.AddFolder(folderToAdd, this.tvMedias.SelectedNode);
                }
                foreach (string file in System.IO.Directory.GetFiles(selFolder))
                {
                    if (System.IO.Path.GetExtension(file).ToLower().EndsWith("jpg"))
                    {
                        ClientTools.Library.Media.Media newImageMedia = this._actMedia.CreateImage(folder.Id, System.IO.Path.GetFileName(file), this.GetImage(file, 1600));
                        TreeNode tnI = new TreeNode(newImageMedia.Name);
                        tnI.Tag = newImageMedia;
                        this.SetImageIndex(tnI, "Image");
                        this.tvMedias.SelectedNode.Nodes.Add(tnI);
                    }
                    else
                    {
                        ClientTools.Library.Media.Media newFileMedia = this._actMedia.CreateFile(folder.Id, System.IO.Path.GetFileName(file), this.GetFile(file));
                        TreeNode tnF = new TreeNode(newFileMedia.Name);
                        tnF.Tag = newFileMedia;
                        this.SetImageIndex(tnF, "File");
                        this.tvMedias.SelectedNode.Nodes.Add(tnF);
                    }
                }
            }
            this.tvMedias.PerformLayout();

            this.Cursor = Cursors.Default;
        }

        private void AddFolder(string folder, TreeNode parentNode)
        {
            ClientTools.Library.Media.Media parentMediaFolder = (ClientTools.Library.Media.Media)parentNode.Tag;
            ClientTools.Library.Media.Media newMediaFolder = this._actMedia.CreateFolder(parentMediaFolder.Id, new System.IO.DirectoryInfo(folder).Name);
            TreeNode tn = new TreeNode(newMediaFolder.Name);
            tn.Tag = newMediaFolder;
            this.SetImageIndex(tn, "Folder");
            parentNode.Nodes.Add(tn);

            foreach (string folderToAdd in System.IO.Directory.GetDirectories(folder))
            {
                this.AddFolder(folderToAdd, tn);
            }
            foreach (string file in System.IO.Directory.GetFiles(folder))
            {
                if (System.IO.Path.GetExtension(file).ToLower().EndsWith("jpg")) 
                {
                    ClientTools.Library.Media.Media newImageMedia = this._actMedia.CreateImage(newMediaFolder.Id, System.IO.Path.GetFileName(file), this.GetImage(file, 1600));
                    TreeNode tnI = new TreeNode(newImageMedia.Name);
                    tnI.Tag = newImageMedia;
                    this.SetImageIndex(tnI, "Image");
                    tn.Nodes.Add(tnI);
                }
                else
                {
                    ClientTools.Library.Media.Media newFileMedia = this._actMedia.CreateFile(newMediaFolder.Id, System.IO.Path.GetFileName(file), this.GetFile(file));
                    TreeNode tnF = new TreeNode(newFileMedia.Name);
                    tnF.Tag = newFileMedia;
                    this.SetImageIndex(tnF, "File");
                    tn.Nodes.Add(tnF);
                }
            }
        }

        private byte[] GetImage(string fileName, int maxImageSize) 
        {
            ImageConverter ic;

            using (System.Drawing.Image image = System.Drawing.Image.FromFile(fileName))
            {
                if (image.Height > maxImageSize || image.Width > maxImageSize)
                {
                    System.Drawing.Bitmap bmp = this.GetScaledImage(image, maxImageSize);
                    string tempFileName = System.IO.Path.GetTempFileName();
                    bmp.Save(tempFileName, System.Drawing.Imaging.ImageFormat.Jpeg);
                    byte[] buffer = this.GetFile(tempFileName);
                    System.IO.File.Delete(tempFileName);
                    return buffer;
                    //'bmp = New System.Drawing.Bitmap(image, image.Width, image.Height)
                } 
                else
	            {
                    ic = new ImageConverter();
                    return (byte[])(ic.ConvertTo(image, typeof(byte[])));
	            }
            }
        }

        private byte[] GetFile(string s)
        {
            using (System.IO.FileStream fs = new System.IO.FileStream(s, System.IO.FileMode.Open))
            {
                byte[] arr = new byte[System.Convert.ToInt32(fs.Length - 1)];
                fs.Position = 0;
                fs.Read(arr, 0, arr.Length);
                fs.Close();
                return arr;
            }
        }

        private System.Drawing.Bitmap GetScaledImage(System.Drawing.Image img, int maxImageSize)
        {
            int w;
            int h;
            double fx;

            if (img.Width > img.Height)
            {
                fx = img.Width / maxImageSize;
                w = maxImageSize;
                h = System.Convert.ToInt32(img.Height / fx);
            }
            else
            {
                if (img.Height > img.Width)
                {
                    fx = img.Height / maxImageSize;
                    h = maxImageSize;
                    w = System.Convert.ToInt32(img.Width / fx);
                }
                else
                {
                    fx = 1;
                    h = maxImageSize;
                    w = maxImageSize;
                }
            }
            return new System.Drawing.Bitmap(img, w, h);
        }

    }
}
